
package codeGenerate.custom.generater;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import codeGenerate.custom.tempalte.TemPathCustomAbstract;
import codeGenerate.custom.vo.CustomConfigVo;
import codeGenerate.custom.vo.CustomPropertyVo;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class CustomGenerater {

	private CustomConfigVo configVo;

	/**
	 * @description: 生成代码
	 * @creator: dw.fu
	 * @createDate: 2015年9月26日 
	 * @modifier:
	 * @modifiedDate:
	 * @throws IOException
	 * @throws TemplateException
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public void generateCode() throws IOException, TemplateException, ClassNotFoundException, InstantiationException, IllegalAccessException {
		System.out.println(">>>>>>>>>>>>>>>>>>>[" + configVo.getBeanDescription() + "]生成开始<<<<<<<<<<<<<<<<<<<");
		System.out.println(configVo);

		Map<String, Object> root = new HashMap<String, Object>();
		//定义模板常量
		root.put("requestColumnList", getRequestColumn());
		root.put("responseColumnList", getResponseColumn());
		root.put("config", configVo);
		Configuration cfg = new Configuration();
		cfg.setClassicCompatible(true);
		cfg.setDirectoryForTemplateLoading(new File(configVo.getTemplateDirectory()));
		cfg.setObjectWrapper(new DefaultObjectWrapper());
		//根据模版路径生成相应的代码
		Class<?> tempateClass = Class.forName(configVo.getTemplate());
		TemPathCustomAbstract temPathAbstract = (TemPathCustomAbstract) tempateClass.newInstance();
		Map<String, String> tplFileMap = temPathAbstract.getPathMap(configVo);
		for (Map.Entry<String, String> entry : tplFileMap.entrySet()) {
			String tempalteFile = entry.getKey();
			String generateFile = entry.getValue();
			Template temp = cfg.getTemplate(tempalteFile);
			File file = new File(generateFile);
			if (!file.exists()) {
				file.getParentFile().mkdirs();
				file.createNewFile();
			}
			OutputStream writer = new FileOutputStream(new File(generateFile));
			Writer out = new OutputStreamWriter(writer);
			temp.process(root, out);
			writer.flush();
			writer.close();
			System.out.println("模板:" + tempalteFile + "==>>生成文件==>>" + generateFile);
		}

		System.out.println(">>>>>>>>>>>>>>>>>>>表名[" + configVo.getBeanDescription() + "]生成结束<<<<<<<<<<<<<<<<<<<");
		System.out.println("\n");
	}

	private List<CustomPropertyVo> getRequestColumn() {
		List<CustomPropertyVo> list = new ArrayList<>();
		String[] columnlines = configVo.getRequest().trim().split("\n");
		for (String columnline : columnlines) {
			String[] columns = columnline.trim().split("\\s+");
			CustomPropertyVo packageColumnVo = new CustomPropertyVo();
			packageColumnVo.setJavaPropertyComment(columns[0]);
			packageColumnVo.setJavaPropertyName(dbColumnNameNameToJavaPropertyName(columns[1]));
			packageColumnVo.setOrginalPropertyName(columns[1]);
			if (columns.length == 3) {
				packageColumnVo.setJavaPropertyType(columns[2]);
			} else {
				//不指定类型，默认String
				packageColumnVo.setJavaPropertyType("String");
			}

			list.add(packageColumnVo);
		}
		return list;
	}

	private List<CustomPropertyVo> getResponseColumn() {
		List<CustomPropertyVo> list = new ArrayList<>();
		String[] columnlines = configVo.getResponse().trim().split("\n");
		for (String columnline : columnlines) {
			String[] columns = columnline.trim().split("\\s+");
			CustomPropertyVo packageColumnVo = new CustomPropertyVo();
			packageColumnVo.setJavaPropertyComment(columns[0]);
			packageColumnVo.setJavaPropertyName(dbColumnNameNameToJavaPropertyName(columns[1]));
			packageColumnVo.setOrginalPropertyName(columns[1]);
			packageColumnVo.setJavaPropertyType("String");
			list.add(packageColumnVo);
		}
		return list;
	}

	/**
	 * @description: 数据库底层的列名转换成属性名称，默认峰驼命名
	 * @creator: dw.fu
	 * @createDate: 2015年9月26日 
	 * @modifier:
	 * @modifiedDate:
	 * @param dbColumnName
	 * @return
	 */
	private String dbColumnNameNameToJavaPropertyName(String dbColumnName) {
		String[] names = dbColumnName.split("_");
		StringBuffer sb = new StringBuffer();
		sb.append(names[0].toLowerCase());
		for (int i = 1; i < names.length; i++) {
			if (StringUtils.isNotBlank(names[i])) {
				sb.append(names[i].substring(0, 1).toUpperCase());
				sb.append(names[i].substring(1).toLowerCase());
			}
		}
		return sb.toString();
	}

	public CustomConfigVo getConfigVo() {
		return configVo;
	}

	public void setConfigVo(CustomConfigVo configVo) {
		this.configVo = configVo;
	}
}
